package com.jy.common.tool;

import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;

public class PositionChecker {

    /**
     * 判断 positionStr 是否在 positionList 的每一个坐标的方圆 20 公里内，只要有一个是就返回 true
     * @param positionStr positionStr
     * @param positionList positionList
     * @return boolean
     */
    public static boolean isWithin20Kilometers(String positionStr, List<String> positionList) {
        // 解析 positionStr 为经度和纬度
        String[] targetParts = positionStr.split(",");
        double targetLon = Double.parseDouble(targetParts[0]);
        double targetLat = Double.parseDouble(targetParts[1]);

        for (String position : positionList) {
            String[] parts = position.split(",");
            double lon = Double.parseDouble(parts[0]);
            double lat = Double.parseDouble(parts[1]);
            // 使用 Haversine 公式计算距离
            double distance = calculateDistance(targetLat, targetLon, lat, lon);
            // 只要有一个位置在 20 公里内，就返回 true
            if (distance <= 20000) {
                return true;
            }
        }
        // 全部位置都不在 20 公里内，返回 false
        return false;
    }


    public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        final int R = 6371; // 地球半径，单位为千米
        double latDistance = Math.toRadians(lat2 - lat1);
        double lonDistance = Math.toRadians(lon2 - lon1);
        double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
                + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
                * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return R * c * 1000; // 转换为米
    }


    /**
     * 首先调用 isWithin20Kilometers 方法检查是否有位置在 20 公里范围内，如果不在则返回 null。
     * 解析 positionStr 为 targetLon 和 targetLat。
     * 初始化 minDistance 为 Double.MAX_VALUE 用于存储最小距离，nearestPosition 存储最近的位置。
     * 遍历 positionList 中的每个元素，计算与 positionStr 的距离。
     * 如果当前距离小于 minDistance，更新 minDistance 和 nearestPosition。
     * @param positionStr positionStr
     * @param positionList positionList
     * @return String[] 数组，第一个元素是最近位置，第二个元素是距离（保留两位小数，单位为 km）
     */
    public static String[] findNearestPositionWithin20Kilometers(String positionStr, List<String> positionList) {
        if (!isWithin20Kilometers(positionStr, positionList)) {
            return null;
        }
        String[] targetParts = positionStr.split(",");
        double targetLon = Double.parseDouble(targetParts[0]);
        double targetLat = Double.parseDouble(targetParts[1]);
        double minDistance = Double.MAX_VALUE;
        String nearestPosition = null;
        for (String position : positionList) {
            String[] parts = position.split(",");
            double lon = Double.parseDouble(parts[0]);
            double lat = Double.parseDouble(parts[1]);
            double distance = calculateDistance(targetLat, targetLon, lat, lon);
            if (distance < minDistance) {
                minDistance = distance;
                nearestPosition = position;
            }
        }
        if (nearestPosition!= null) {
            String[] nearestParts = nearestPosition.split(",");
            double nearestLon = Double.parseDouble(nearestParts[0]);
            double nearestLat = Double.parseDouble(nearestParts[1]);
            double finalDistance = calculateDistance(targetLat, targetLon, nearestLat, nearestLon);
            // 保留两位小数
            DecimalFormat df = new DecimalFormat("#.##");
            String formattedDistance = df.format(finalDistance / 1000);
            return new String[]{nearestPosition, formattedDistance};
        }
        return null;
    }

    public static void main(String[] args) {
        // 示例使用
        String positionStr = "120.027335,28.28932513";
        List<String> positionList = java.util.Arrays.asList(
                "120.030423,28.928350",
                "120.027335,28.28932513",
                "120.042757,28.919838",
                "120.054258,28.887756"
        );
        boolean result = isWithin20Kilometers(positionStr, positionList);
        System.out.println(result);
        String[] nearestResult = findNearestPositionWithin20Kilometers(positionStr, positionList);
        if (nearestResult!= null) {
            System.out.println("Nearest position within 20 kilometers: " + nearestResult[0]);
            System.out.println("Distance to nearest position: " + nearestResult[1] + " km");
        } else {
            System.out.println("No position within 20 kilometers.");
        }
    }
}